home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Pascal / Source□ / sndDemo ƒ / sndDemo.p next >
Encoding:
Text File  |  1993-03-25  |  5.8 KB  |  162 lines  |  [TEXT/PJMM]

  1. program sndDemo;
  2.  
  3. { I spent a hard week getting this demo of the playing of an asynchronous sound to work }
  4. { in Think Pascal 4.0.2. My main difficulty was that it won't work with the [D] Debug switch set }
  5. { on the compile options. But the manual doesn't contain all of the necessary information.  }
  6. { Some essential ideas were gleaned from Jim Reekes' pSoundApp example in the DTS folder }
  7. { of ftp.apple.com.  Since it was so touchy, I thought others might benefit from this demo. }
  8. {  }
  9. { This code is terse. I have stripped out everything but the essentials. It should be used }
  10. { in conjuntion with chapter 22 of volume VI of Inside Macintosh. I have deliberately left }
  11. { out all error checking so as to not obscure the essential code. Although in all my testing }
  12. { I never saw an error that wasn't a result of my stupidity or ignorance. I have included a }
  13. { few extra inline procedure declarations to make it easier to build this demo into a real program. }
  14. {  }
  15. { To play an asynchronous sound - that is, a sound that plays while other things are happening, }
  16. { one must define a callBack procedure. This procedure can't do much because it will be invoked }
  17. { at interrupt time and won't have access to your normal program environment. To access your }
  18. { global variables, you must restore register A5. Most of the callBack code is concerned with }
  19. { restoring A5; and all the callback procedure does is set a switch 'sndProgress := 2' so that you }
  20. { can tell (elsewhere) that the sound has finished. }
  21. {  }
  22. { Two global variables are needed: }
  23. { - The integer sndProgress is meant to have the value 0 when no sound is playing, 1 when a sound}
  24. {    is playing, and 2 when a sound has finished but the resources haven't been released yet. }
  25. { - The sndChannelPtr mySndChannel is given a value when a sound channel is allocated in the }
  26. {    routine that starts the sound playing (aSyncStartPlay), and is needed to dispose of the channel }
  27. {    when the sound has completed and must be disposed (aSyncEndPlay). }
  28. {  }
  29. { If you use these routines to play async sounds, you will want a line of code in your main}
  30. { event loop to dispose of the channel and sound handle as soon as the sound has completed:}
  31. {           if sndProgress = 2 then                }
  32. {                aSyncEndPlay(sndChannel);     }
  33. {  }
  34. { What this demo program does, is start the sound playing and then count until the sound is done. }
  35. { The count is written to the text window. It does this five times. You must open the window manually }
  36. { and place it strategically if you want to watch the counting as the sound is played. }
  37. { ------------------------------------------------------------------------------------------ }
  38. { Marv Westrom }
  39. { Mathematics and Science Education (Computing Studies Education) }
  40. { The University of British Columbia }
  41. { Vancouver, B.C.   Canada    V6T 1Z4 }
  42. { ------------------------------------------------------------------------------------------ }
  43. { March 24, 1993.}
  44. { ------------------------------------------------------------------------------------------ }
  45.  
  46.     const
  47.         stdQLength = 128;
  48.         NoSynth = 0;        { no specified synth for channel }
  49.         InitNone = 0;        { no specified init parameters for channel }
  50.  
  51.     type
  52.         SndCommand = packed record
  53.                 cmd: INTEGER;
  54.                 param1: INTEGER;
  55.                 param2: LONGINT;
  56.             end;
  57.         Time = LONGINT;    { in half milliseconds }
  58.         SndChannelPtr = ^SndChannel;
  59.         SndChannel = packed record
  60.                 nextChan: SndChannelPtr;
  61.                 firstMod: Ptr;{ reserved for the Sound Manager }
  62.                 callBack: ProcPtr;
  63.                 userInfo: LONGINT;
  64.                 wait: Time;    { The following is for internal Sound Manager use only.}
  65.                 cmdInProgress: SndCommand;
  66.                 flags: INTEGER;
  67.                 qLength: INTEGER;
  68.                 qHead: INTEGER;
  69.                 qTail: INTEGER;
  70.                 queue: array[1..stdQLength] of SndCommand;
  71.             end;
  72.  
  73.     var { necessary globals }
  74.         mySndChannel: SndChannelPtr;
  75.         sndProgress: integer;
  76.  
  77.     function SndDisposeChannel (chan: sndChannelPtr; quietNow: BOOLEAN): OSErr;
  78.     inline
  79.         $A801;
  80.     function SndDoCommand (chan: sndChannelPtr; cmd: SndCommand; noWait: BOOLEAN): OSErr;
  81.     inline
  82.         $A803;
  83.     function SndDoImmediate (chan: sndChannelPtr; cmd: SndCommand): OSErr;
  84.     inline
  85.         $A804;
  86.     function SndPlay (chan: SndChannelPtr; sndHdl: Handle; async: BOOLEAN): OSErr;
  87.     inline
  88.         $A805;
  89.     function SndNewChannel (var chan: SndChannelPtr; synth: INTEGER; init: LONGINT; userRoutine: ProcPtr): OSErr;
  90.     inline
  91.         $A807;
  92.     function setCurrentA5: longint;
  93.     inline
  94.         $2E8D, $2A78, $0904;
  95.     function setA5 (newA5: longint): longint;
  96.     inline
  97.         $2F4D, $0004, $2A5F;
  98.  
  99.     procedure myCallBack (Chan: sndChannelPtr; cmd: sndCommand);
  100.         var
  101.             myA5: longint;
  102.     begin
  103.         if cmd.param1 = 99 then
  104.             begin
  105.                 myA5 := setA5(cmd.param2);
  106.                 sndProgress := 2;
  107.                 myA5 := SetA5(myA5);
  108.             end;
  109.     end;
  110.  
  111.     procedure aSyncStartPlay (sndH: handle);
  112.         var
  113.             mySndCmd: sndCommand;
  114.             myErr: OSErr;
  115.     begin
  116.         LoadResource(sndH);
  117.         moveHHi(sndH);
  118.         Hlock(sndH);
  119.         mySndChannel := nil;
  120.         myErr := SndNewChannel(mySndChannel, NoSynth, InitNone, @myCallBack);
  121.         myErr := sndPlay(mySndChannel, sndH, true);
  122.         sndProgress := 1;
  123.         mySndCmd.cmd := 13;        { callBackCmd }
  124.         mySndCmd.param1 := 99; { arbitrary code to check myCallback }
  125.         mySndCmd.param2 := setCurrentA5;
  126.         myErr := sndDoCommand(mySndChannel, mySndCmd, false);
  127.     end;
  128.  
  129.     procedure aSyncEndPlay (sndH: handle);
  130.         var
  131.             mySndCmd: sndCommand;
  132.             myErr: OSErr;
  133.     begin
  134.         mySndCmd.cmd := 3;        { quietCmd }
  135.         myErr := sndDoCommand(mySndChannel, mySndCmd, false);
  136.         myErr := sndDisposeChannel(mySndChannel, true);
  137.         HUnlock(sndH);
  138.         sndProgress := 0;
  139.     end;
  140.  
  141.     var
  142.         sndHiThere: handle;
  143.         i, times: integer;
  144.  
  145. begin
  146.     sndProgress := 0;
  147.     sndHiThere := getnamedresource('snd ', 'Hi There');
  148.     for times := 1 to 5 do
  149.         begin
  150.             writeln;
  151.             writeln('Hi there ', times : 2);
  152.             aSyncStartPlay(sndHiThere);
  153.             i := 0;
  154.             repeat
  155.                 i := i + 1;
  156.                 write(i : 3);
  157.                 if (i mod 25) = 0 then
  158.                     writeln;
  159.             until sndProgress = 2;
  160.             aSyncEndplay(sndHiThere);
  161.         end;
  162. end.